# -*- coding: utf-8 -*-
"""
Module Description:
Date: 2018/12/12
Author: FQ

2.5版本之后，跨服业务可直接抛CrossGameException异常，区服response处理，可以不用再定义特殊状态，
直接使用ResponseBase.response_callback方法

"""
import copy

import zope.component

from common.service_config import get_role_guid
from pyshare.bll import events
from pyshare.bll.utils.area.res_utils import res_type_to_activity_type
from pyshare.dal.repository_impl.character_center import DistributedTransactionStatRepository
from pyshare.const.lang.tips_info import TipsInfo
from pyshare.const.enums.activity import ReturnStat
from pyshare.const.enums.cross_cate import CateReturnStat
from pyshare.const.enums.cross_ruins import RuinsReturnStat
from pyshare.const.enums.cross_siege import SiegeReturnStat
from pyshare.const.enums.cross_chess import ChessReturnStat
from pyshare.const.enums.cross_prince_marry import CrossPrinceMarryReturnStat
from pyshare.const.enums.cross_soccer import SoccerReturnStat
from pyshare.const.enums.cross_rehearse import RehearseReturnStat
from pyshare.core.context import get_trace_id
from pyshare.utils.service_switch import is_open_dts
from pyshare.framework.error_handle import GameException
from pyshare.const.enums.dts_stat import CrossStat
from pyshare.framework.dal.dal_manager import TransactionDelegator
from pyshare.const.enums.dts_stat import AreaStat, Stat
from pyshare.framework.firefly_dc.global_errcode import GlobalErrCode


# 服务器常规状态
Normal_Stat = (GlobalErrCode.ERROR, GlobalErrCode.FAILED, GlobalErrCode.ILLEGAL_ACTION,
               GlobalErrCode.SERVER_MAINTAINING, GlobalErrCode.PLEASE_TRY_AGAIN)


class ResponseBase(object):
    """
    跨服返回数据处理基类
    """

    @staticmethod
    def normal_response(res):
        # raise Exception('not normal response function')
        del res['Stat']
        return res

    @classmethod
    def do_response(cls, res):
        if res['Stat'] in Normal_Stat:
            extra = copy.deepcopy(res)
            del extra["Info"]
            del extra["Stat"]
            raise GameException(res.get('Info', ''), extra=extra)
        # 有资源更新 更新任务进度
        # 触发活动事件
        progress_list = res.get("ProgressList", [])
        for progress in progress_list:
            is_trigger_event = progress.get("IsTriggerEvent", True)
            num = progress.get("Num", 0)
            r_type = progress.get("Type", 0)
            if is_trigger_event and num < 0 and r_type in res_type_to_activity_type:
                event = events.ActivityProgressChanged(
                    role_id=get_role_guid(),
                    a_type=res_type_to_activity_type[r_type],
                    add_value=-num)
                zope.component.handle(event)
        return cls.normal_response(res)

    @classmethod
    def response_callback(cls, res, try_consistent=False):
        """
        对外调用的返回处理
        :param res: 返回结果
        :param try_consistent: 远程服务不可用时 是否尝试一致性处理
        :return:
        """
        try:
            if not res or 'Stat' not in res:
                # 无返回结果
                if try_consistent and is_open_dts():
                    # 从跨服操作记录中获取此次请求的结果
                    try:
                        with TransactionDelegator():
                            stat_record = DistributedTransactionStatRepository.get_by_trace_id(get_trace_id())
                            DistributedTransactionStatRepository.set_already_read(get_trace_id())
                    except Exception as e:
                        stat_record = None
                        from pyshare.framework import runtime_logger as log
                        # 将AreaStat已读的状态写入log
                        error_msg = 'DistributedTransactionStat get_by_trace_id failed, ' + str(e.message)
                        log.error({'Error': error_msg, 'Stat': Stat.LinkLoss, 'AreaStat': AreaStat.TryDtsRes})
                    if not stat_record or stat_record.cross_stat != CrossStat.Complete or not stat_record.res:
                        # 无记录或跨服未操作完成
                        raise GameException(TipsInfo.CrossActivity.CrossServiceError)

                    return cls.do_response(stat_record.res)
                else:
                    raise GameException(TipsInfo.CrossActivity.CrossServiceError)
        except Exception as e:
            raise e
        finally:
            # 删除开关复用中间件开关
            if try_consistent and is_open_dts():
                DistributedTransactionStatRepository.delete_by_trace_id(get_trace_id())
            # TODO 暂时不删除此次请求的跨服的操作记录
            pass
        return cls.do_response(res)


class CrossRankResponse(ResponseBase):
    """
    跨服冲榜返回数据
    """

    @staticmethod
    def normal_response(res):
        """
        常规返回结果处理
        :param res:
        :return:
        """
        if res['Stat'] == ReturnStat.ActivityOver:
            # 活动已结束
            raise GameException(TipsInfo.CrossActivity.ActivityOver)
        elif res['Stat'] == ReturnStat.OverAndSend:
            # 活动已结束, 奖励已发送
            raise GameException(TipsInfo.CrossActivity.activityExpire)
        elif res['Stat'] == ReturnStat.ServerNotJoin:
            # 区服不在参与列表中
            raise GameException(TipsInfo.CrossActivity.ServerNotIn)
        elif res['Stat'] == ReturnStat.InPrepare:
            # 活动预热中
            raise GameException(TipsInfo.CrossActivity.NotStart)
        elif res['Stat'] == ReturnStat.NotAwardTime:
            # 未到领奖时间
            raise GameException(TipsInfo.CrossActivity.NotAwardTime)
        elif res['Stat'] == ReturnStat.AlreadyAward:
            # 已领取奖励
            raise GameException(TipsInfo.CrossActivity.GetAwardAlready)
        elif res['Stat'] == ReturnStat.NotReachAWard:
            # 未达成
            raise GameException(TipsInfo.CrossActivity.NotReachAward)

        elif res['Stat'] in Normal_Stat:
            raise GameException(res['Info'])
        else:

            del res['Stat']

        return {'status': True, 'Res': res}


class CrossSiegeResponse(ResponseBase):
    """
    跨服攻城战返回数据
    """

    @staticmethod
    def normal_response(res):
        """
        常规返回结果处理
        :param res:
        :return:
        """
        if res['Stat'] == SiegeReturnStat.ActivityOver:
            # 活动已结束
            raise GameException(TipsInfo.CrossSiege.ActivityOver)
        elif res['Stat'] == SiegeReturnStat.OverAndSend:
            # 活动已结束, 奖励已发送
            raise GameException(TipsInfo.CrossSiege.activityExpire)
        elif res['Stat'] == SiegeReturnStat.ServerNotJoin:
            # 区服不在参与列表中
            raise GameException(TipsInfo.CrossSiege.ServerNotIn)
        elif res['Stat'] == SiegeReturnStat.InPrepare:
            # 活动预热中
            raise GameException(TipsInfo.CrossSiege.NotStart)
        elif res['Stat'] == SiegeReturnStat.NotAwardTime:
            # 未到领奖时间
            raise GameException(TipsInfo.CrossSiege.NotAwardTime)
        elif res['Stat'] == SiegeReturnStat.AlreadyAward:
            # 已领取奖励
            raise GameException(TipsInfo.CrossSiege.GetAwardAlready)
        elif res['Stat'] == SiegeReturnStat.NotReachAWard:
            # 未达成
            raise GameException(TipsInfo.CrossSiege.NotReachAward)
        elif res['Stat'] == SiegeReturnStat.RankTypeError:
            # 未达成
            raise GameException(TipsInfo.CrossSiege.RankTypeError)
        elif res['Stat'] == SiegeReturnStat.PeriodError:
            # 阶段错误
            raise GameException(TipsInfo.CrossSiege.PeriodError)
        elif res['Stat'] == SiegeReturnStat.HasBattleCity:
            # 已有交战城池
            raise GameException(TipsInfo.CrossSiege.HasBattleCity)
        elif res['Stat'] == SiegeReturnStat.AtkCityHasBeenBroken:
            # 攻方城池已被攻破
            if 'CrossSiegeBattleStat' in res:
                return {'status': False,
                        'Stat': SiegeReturnStat.AtkCityHasBeenBroken,
                        'CrossSiegeBattleStat': res.get('CrossSiegeBattleStat')}
            else:
                raise GameException(TipsInfo.CrossSiege.AtkCityHasBeenBroken)
        elif res['Stat'] == SiegeReturnStat.MinisterHasBeenBroken:
            # 大臣已被击败
            if 'CrossSiegeBattleStat' in res:
                return {'status': False,
                        'Stat': SiegeReturnStat.MinisterHasBeenBroken,
                        'DefCityHP': res.get('DefCityHP'),
                        'CrossSiegeBattleStat': res.get('CrossSiegeBattleStat')}
            else:
                raise GameException(TipsInfo.CrossSiege.MinisterHasBeenBroken)
        elif res['Stat'] == SiegeReturnStat.NotEnoughVit:
            # 大臣体力不足
            raise GameException(TipsInfo.CrossSiege.NotEnoughVit)
        elif res['Stat'] == SiegeReturnStat.ParamError:
            # 参数错误
            # raise GameException(TipsInfo.GlobalKeys.paramError)
            return {
                'status': False,
                'info': TipsInfo.GlobalKeys.paramError
            }
        elif res['Stat'] == SiegeReturnStat.DefCityHasBeenBroken:
            # 守方城池已被攻破
            if 'CrossSiegeBattleStat' in res:
                return {'status': False,
                        'Stat': SiegeReturnStat.DefCityHasBeenBroken,
                        'CrossSiegeBattleStat': res.get('CrossSiegeBattleStat')}
            else:
                raise GameException(TipsInfo.CrossSiege.DefCityHasBeenBroken)
        elif res['Stat'] == SiegeReturnStat.OverMaxNum:
            # 超出购买次数
            raise GameException(TipsInfo.ShopKeys.overMaxNum)
        elif res['Stat'] == SiegeReturnStat.NotQualified:
            # 不在资格名单中
            raise GameException(TipsInfo.CrossSiege.NotInActor)
        elif res['Stat'] == SiegeReturnStat.NotInActor:
            # 不在资格名单中
            raise GameException(TipsInfo.CrossSiege.NotInActor)
        elif res['Stat'] == SiegeReturnStat.CfgError:
            # 配置错误
            raise GameException(TipsInfo.RoleKeys.configError)
        elif res['Stat'] == SiegeReturnStat.DataError:
            # 数据错误
            raise GameException(TipsInfo.RoleKeys.dataError)
        elif res['Stat'] == SiegeReturnStat.ChestAlreadyInvalid:
            # 该宝箱已经失效
            raise GameException(TipsInfo.CrossSiege.ChestAlreadyInvalid)
        elif res['Stat'] == SiegeReturnStat.ChestAlreadyOverdue:
            # 该宝箱已经过期
            raise GameException(TipsInfo.CrossSiege.ChestAlreadyOverdue)

        elif res['Stat'] in Normal_Stat:
            raise GameException(res['Info'])
        else:
            del res['Stat']
            del res['ActionId']

        return {'status': True, 'Res': res}


class CrossRuinsResponse(ResponseBase):
    """
    跨服遗迹返回数据
    """

    @staticmethod
    def normal_response(res):
        """
        常规返回结果处理
        :param res:
        :return:
        """

        if res['Stat'] == RuinsReturnStat.ActivityOver:
            # 活动已结束
            raise GameException(TipsInfo.CrossRuins.ActivityOver)
        elif res['Stat'] == RuinsReturnStat.ActivityNotExist:
            # 活动不存在
            raise GameException(TipsInfo.CrossRuins.ActivityOver)
        elif res['Stat'] == RuinsReturnStat.StageTypeError:
            # 阶段奖励类型错误
            raise GameException(TipsInfo.CrossRuins.StageTypeError)
        elif res['Stat'] == RuinsReturnStat.OverAndSend:
            # 活动已结束, 奖励已发送
            raise GameException(TipsInfo.CrossRuins.activityExpire)
        elif res['Stat'] == RuinsReturnStat.ServerNotJoin:
            # 区服不在参与列表中
            raise GameException(TipsInfo.CrossRuins.ServerNotIn)
        elif res['Stat'] == RuinsReturnStat.NotInReachAwardTime:
            # 未到领奖时间
            raise GameException(TipsInfo.CrossRuins.NotAwardTime)
        elif res['Stat'] == RuinsReturnStat.GetAwardAlready:
            # 已领取奖励
            raise GameException(TipsInfo.CrossRuins.GetAwardAlready)
        elif res['Stat'] == RuinsReturnStat.NotReachAWard:
            # 未达成
            raise GameException(TipsInfo.CrossRuins.NotReachAward)
        elif res['Stat'] == RuinsReturnStat.RankTypeError:
            # 未达成
            raise GameException(TipsInfo.CrossRuins.RankTypeError)

        elif res['Stat'] == RuinsReturnStat.ParamsError:
            # 参数错误
            raise GameException(TipsInfo.GlobalKeys.paramError)

        elif res['Stat'] == RuinsReturnStat.NotQualified:
            # 不在资格名单中
            raise GameException(TipsInfo.CrossRuins.NotInActor)
        elif res['Stat'] == RuinsReturnStat.DataError:
            # 数据错误
            raise GameException(TipsInfo.RoleKeys.dataError)
        elif res['Stat'] == RuinsReturnStat.CfgError:
            # 配置错误错误
            raise GameException(TipsInfo.RoleKeys.configError)
        elif res['Stat'] == RuinsReturnStat.CanNotSendMinister:
            # 不能派遣大臣
            raise GameException(TipsInfo.CrossRuins.CanNotSendMinister)
        elif res['Stat'] == RuinsReturnStat.MinisterWasDeath:
            # 大臣已经死亡
            raise GameException(TipsInfo.CrossRuins.MinisterWasDeath)
        elif res['Stat'] == RuinsReturnStat.NotPowerCanFind:
            # 没有体力可以搜寻
            raise GameException(TipsInfo.CrossRuins.NotPowerCanFind)
        elif res['Stat'] == RuinsReturnStat.AlreadyOpenChest:
            # 已经打开宝箱
            raise GameException(TipsInfo.CrossRuins.AlreadyOpenChest)
        elif res['Stat'] == RuinsReturnStat.NotPowerCanRun:
            # 没有体力可以移动
            raise GameException(TipsInfo.CrossRuins.NotPowerCanRun)
        elif res['Stat'] == RuinsReturnStat.CanNotRun:
            # 不能移动
            raise GameException(TipsInfo.CrossRuins.CanNotRun)
        elif res['Stat'] == RuinsReturnStat.ShrinkScopeFailure:
            # 缩圈失败
            raise GameException(TipsInfo.CrossRuins.ShrinkScopeFailure)
        elif res['Stat'] == RuinsReturnStat.IsShrinkingScope:
            # 正在缩圈
            raise GameException(TipsInfo.CrossRuins.IsShrinkingScope, extra={"Refresh": 21})

        elif res['Stat'] in Normal_Stat:
            raise GameException(res['Info'])
        else:
            del res['Stat']
            del res['ActionId']

        return {'status': True, 'Res': res}


class CrossCateResponse(ResponseBase):
    """
    跨服美食返回数据
    """

    @staticmethod
    def normal_response(res):
        """
        常规返回结果处理
        ActivityOver = 1        # 活动已结束
    NotMakeTime = 2         # 当前时间无法制作
    NotPillageTime = 3      # 当前时间无法捞取
    NotAwardTime = 4        # 当前时间无法领取奖励
    ParamError = 5          # 参数错误
    DataError = 6           # 数据错误
    FoodNotCooked = 7       # 食物未熟
    NotActivityTime = 8     # 非活动期间
    InCD = 9                # CD冷却中
    AwardAlready = 10       # 已领取奖励
    AwardNotAchieve = 11    # 未达成领取条件
    ServerNotJoin = 12      # 区服未参与活动
    OverAndSend = 13        # 活动已结束，并发送奖励邮件
    ConfigError = 14        # 配置错误
        :param res:
        :return:
        """
        if res['Stat'] == CateReturnStat.ActivityOver:
            # 活动已结束
            raise GameException(TipsInfo.CrossActivity.ActivityOver)
        elif res['Stat'] == CateReturnStat.NotMakeTime:
            # 当前时间无法制作
            raise GameException(TipsInfo.CrossCateActivity.NotMakeTime)
        elif res['Stat'] == CateReturnStat.NotPillageTime:
            # 当前时间无法捞取
            raise GameException(TipsInfo.CrossCateActivity.NotPillageTime)
        elif res['Stat'] == CateReturnStat.NotAwardTime:
            # 非领奖时段
            raise GameException(TipsInfo.CrossCateActivity.NotAwardTime)
        elif res['Stat'] == CateReturnStat.ParamError:
            # 参数错误
            raise GameException(TipsInfo.GlobalKeys.paramError)
        elif res['Stat'] == CateReturnStat.DataError:
            # 数据错误
            raise GameException(TipsInfo.RoleKeys.dataError)
        elif res['Stat'] == CateReturnStat.FoodNotCooked:
            # 食物未熟
            raise GameException((TipsInfo.CrossCateActivity.FoodNotCooked, res['CD']))
        elif res['Stat'] == CateReturnStat.NotActivityTime:
            # 非活动时间
            raise GameException(TipsInfo.CrossCateActivity.NotActivityTime)
        elif res['Stat'] == CateReturnStat.InCD:
            # CD冷却中
            raise GameException(TipsInfo.CrossCateActivity.InCD)
        elif res['Stat'] == CateReturnStat.OverAndSend:
            # 活动已结束, 奖励已发送
            raise GameException(TipsInfo.CrossActivity.activityExpire)
        elif res['Stat'] == CateReturnStat.ServerNotJoin:
            # 区服不在参与列表中
            raise GameException(TipsInfo.CrossActivity.ServerNotIn)
        elif res['Stat'] == CateReturnStat.AwardAlready:
            # 已领取奖励
            raise GameException(TipsInfo.CrossActivity.GetAwardAlready)
        elif res['Stat'] == CateReturnStat.AwardNotAchieve:
            # 未达成
            raise GameException(TipsInfo.CrossActivity.NotReachAward)
        elif res['Stat'] == CateReturnStat.ConfigError:
            # 配置错误
            raise GameException(TipsInfo.RoleKeys.configError)
        elif res['Stat'] == CateReturnStat.VitNotEnough:
            # 体力不足
            raise GameException(TipsInfo.CrossCateActivity.VitNotEnough)
        elif res['Stat'] == CateReturnStat.ActivityNotStart:
            # 活动未开始
            raise GameException(TipsInfo.CrossCateActivity.VitNotEnough)
        elif res['Stat'] in Normal_Stat:
            raise GameException(res['Info'])
        else:
            del res['Stat']

        return {'status': True, 'Res': res}


class CrossChessResponse(ResponseBase):
    """
    跨服棋局返回数据
    """

    @staticmethod
    def normal_response(res):
        """
        常规返回结果处理
        TeamNameUsed = 1            # 该名称已被占用，请重新命名
        TeamNotExist = 2            # 队伍不存在
        TooLowerCombatForJoin = 3   # 你的战力未达到队伍需求，无法加入
        TooLowerCombatForApply = 4  # 你的战力未达到队伍需求，无法申请
        TeamIsFull = 5              # 队伍已满
        JoinAlready = 6             # 已加入队伍
        MemberJoinCD = 7            # 玩家加入队伍CD中
        RecruitCD = 8               # 队伍处于招募CD中
        ApplyLimit = 9              # 已达申请上限
        ApplyDiffServer = 10        # 只能申请同区服的队伍
        NotTeamLeader = 11          # 不是队长
        ApplyInvalid = 12           # 入队申请无效
        LeaderCanNotLeave = 13      # 队长不能离开队伍
        SearchDiffServer = 14       # 只能搜索同区服的队伍
        ActivityNotExist = 15       # 活动不存在
        ActivityEnd = 16            # 活动已结束
        ActivityNotInDailyTime = 17  # 活动未开放
        NotAwarding = 18            # 非领奖时间
        :param res:
        :return:
        """
        if res['Stat'] == ChessReturnStat.TeamNameUsed:
            # 队伍名称重复
            raise GameException(TipsInfo.CrossChessActivity.TeamNameUsed)
        elif res['Stat'] == ChessReturnStat.TeamNotExist:
            # 队伍不存在
            raise GameException(TipsInfo.CrossChessActivity.TeamNotExist)
        elif res['Stat'] == ChessReturnStat.TooLowerCombatForJoin:
            # 你的战力未达到队伍需求，无法加入
            raise GameException(TipsInfo.CrossChessActivity.TooLowerCombatForJoin)
        elif res['Stat'] == ChessReturnStat.TooLowerCombatForApply:
            # 你的战力未达到队伍需求，无法加入
            raise GameException(TipsInfo.CrossChessActivity.TooLowerCombatForApply)
        elif res['Stat'] == ChessReturnStat.TeamIsFull:
            # 当前队伍已满人，无法加入
            raise GameException(TipsInfo.CrossChessActivity.TeamIsFull)
        elif res['Stat'] == ChessReturnStat.JoinAlready:
            # 已加入队伍
            raise GameException(TipsInfo.CrossChessActivity.JoinAlready)
        elif res['Stat'] == ChessReturnStat.MemberJoinCD:
            # 玩家加入队伍冷却CD中
            raise GameException(TipsInfo.CrossChessActivity.MemberJoinCD)
        elif res['Stat'] == ChessReturnStat.RecruitCD:
            # 队伍处于招募CD中
            raise GameException(TipsInfo.CrossChessActivity.RecruitCD)
        elif res['Stat'] == ChessReturnStat.ApplyLimit:
            # 已达申请上限
            raise GameException(TipsInfo.CrossChessActivity.ApplyLimit)
        elif res['Stat'] == ChessReturnStat.ApplyDiffServer:
            # 只能申请同区服的队伍
            raise GameException(TipsInfo.CrossChessActivity.ApplyDiffServer)
        elif res['Stat'] == ChessReturnStat.NotTeamLeader:
            # 不是队长
            raise GameException(TipsInfo.CrossChessActivity.NotTeamLeader)
        elif res['Stat'] == ChessReturnStat.ApplyInvalid:
            # 入队申请无效
            raise GameException(TipsInfo.CrossChessActivity.ApplyInvalid)
        elif res['Stat'] == ChessReturnStat.LeaderCanNotLeave:
            # 队长不能离开队伍
            raise GameException(TipsInfo.CrossChessActivity.LeaderCanNotLeave)
        elif res['Stat'] == ChessReturnStat.SearchDiffServer:
            # 只能搜索同区服的队伍
            raise GameException(TipsInfo.CrossChessActivity.SearchDiffServer)
        elif res['Stat'] == ChessReturnStat.ActivityNotExist:
            # 活动不存在
            raise GameException(TipsInfo.CrossChessActivity.ActivityNotExist)
        elif res['Stat'] == ChessReturnStat.ActivityEnd:
            # 活动已结束
            raise GameException(TipsInfo.CrossChessActivity.ActivityEnd)
        elif res['Stat'] == ChessReturnStat.ActivityNotInDailyTime:
            # 活动未开放
            raise GameException(TipsInfo.CrossChessActivity.ActivityNotInDailyTime)
        elif res['Stat'] == ChessReturnStat.NotAwarding:
            # 非领奖时间
            raise GameException(TipsInfo.CrossChessActivity.NotAwarding)
        elif res['Stat'] == ChessReturnStat.RankTypeError:
            # 榜单类型错误
            raise GameException(TipsInfo.CrossChessActivity.RankTypeError)
        elif res['Stat'] == ChessReturnStat.AwardAlready:
            # 已领取奖励
            raise GameException(TipsInfo.CrossChessActivity.AwardAlready)
        elif res['Stat'] == ChessReturnStat.NotAchieveAward:
            # 排名奖励未达成
            raise GameException(TipsInfo.CrossChessActivity.NotAchieveAward)
        elif res['Stat'] == ChessReturnStat.NotJoinTeam:
            # 未加入队伍
            raise GameException(TipsInfo.CrossChessActivity.NotJoinTeam)
        elif res['Stat'] == ChessReturnStat.InviteInvalid:
            # 未加入队伍
            raise GameException(TipsInfo.CrossChessActivity.InviteInvalid)
        # 战斗
        elif res['Stat'] == ChessReturnStat.DataError:
            # 数据错误
            raise GameException(TipsInfo.RoleKeys.dataError)
        elif res['Stat'] == ChessReturnStat.CfgError:
            # 配置错误
            raise GameException(TipsInfo.RoleKeys.configError)
        elif res['Stat'] == ChessReturnStat.ChessAlreadyMark:
            # 该事件已经被标记
            raise GameException(TipsInfo.CrossChessActivity.ChessAlreadyMark)
        elif res['Stat'] == ChessReturnStat.ChessNotPowerSearch:
            # 当前体力不足，无法搜索
            raise GameException(TipsInfo.CrossChessActivity.ChessNotPowerSearch)
        elif res['Stat'] == ChessReturnStat.ChessAlreadyMark:
            # 该事件已经被标记
            raise GameException(TipsInfo.CrossChessActivity.ChessAlreadyMark)
        elif res['Stat'] == ChessReturnStat.ChessBattleInCd:
            # 战斗cd中
            raise GameException(TipsInfo.CrossChessActivity.ChessBattleInCd)
        elif res['Stat'] == ChessReturnStat.ChessNpcAlreadyDeath:
            # 该Npc已经死亡
            raise GameException("", stat=ChessReturnStat.ChessNpcAlreadyDeath)
        elif res['Stat'] == ChessReturnStat.ChessPlayerAlreadyDeath:
            # 该玩家已经死亡
            raise GameException("", stat=ChessReturnStat.ChessPlayerAlreadyDeath)
        elif res['Stat'] == ChessReturnStat.ChessAlreadyOpenProp:
            # 已经打开该道具
            raise GameException(TipsInfo.CrossChessActivity.ChessAlreadyOpenProp)
        elif res['Stat'] == ChessReturnStat.ChessNpcUpgradeFloorNotEnough:
            # 击杀Npc数目不足以晋升上一层
            raise GameException(TipsInfo.CrossChessActivity.ChessNpcUpgradeFloorNotEnough)
        elif res['Stat'] == ChessReturnStat.ChessPassCardUpgradeFloorNotEnough:
            # 心境值不足以晋升上一层
            raise GameException(TipsInfo.CrossChessActivity.ChessPassCardUpgradeFloorNotEnough)
        elif res['Stat'] == ChessReturnStat.ChessChestAlreadyInvalid:
            # 该宝箱已经失效
            raise GameException(TipsInfo.CrossChessActivity.ChessChestAlreadyInvalid)
        elif res['Stat'] == ChessReturnStat.ChessHelpInCd:
            # 援助cd中
            raise GameException(TipsInfo.CrossChessActivity.ChessHelpInCd)
        elif res['Stat'] == ChessReturnStat.NoTeamCanAutoJoin:
            # 无满足条件的队伍可随机加入
            raise GameException(TipsInfo.CrossChessActivity.NoTeamCanAutoJoin)
        elif res['Stat'] == ChessReturnStat.ChessBuyTimeNotEnough:
            # 购买体力次数不足
            raise GameException(TipsInfo.CrossChessActivity.ChessBuyTimeNotEnough)
        elif res['Stat'] == ChessReturnStat.ChessNotTeamCanNotMark:
            # 没有队伍不能标记
            raise GameException(TipsInfo.CrossChessActivity.ChessNotTeamCanNotMark)
        elif res['Stat'] == ChessReturnStat.AlreadyApply:
            # 已申请
            raise GameException(TipsInfo.CrossChessActivity.AlreadyApply)
        elif res['Stat'] == ChessReturnStat.AlreadyInvite:
            # 已邀请
            raise GameException(TipsInfo.CrossChessActivity.AlreadyInvite)
        elif res['Stat'] == ChessReturnStat.ChessCanNotBattleTeam:
            # 不能攻击队友
            raise GameException(TipsInfo.CrossChessActivity.ChessCanNotBattleTeam)
        elif res['Stat'] == ChessReturnStat.ChessCanNotMarkTeam:
            # 无法标记队友
            raise GameException(TipsInfo.CrossChessActivity.ChessCanNotMarkTeam)

        elif res['Stat'] == ChessReturnStat.CancelApplyAlready:
            # 已取消
            raise GameException(TipsInfo.CrossChessActivity.CancelApplyAlready)

        elif res['Stat'] == ChessReturnStat.SelfJoinAlready:
            # 你已加入队伍
            raise GameException(TipsInfo.CrossChessActivity.SelfJoinAlready)

        elif res['Stat'] == ChessReturnStat.AlreadyLeave:
            # 该君王已离开队伍
            raise GameException(TipsInfo.CrossChessActivity.AlreadyLeave)

        elif res['Stat'] == ChessReturnStat.ChessMarkInvalid:
            # 改标记已经失效
            raise GameException(TipsInfo.CrossChessActivity.ChessMarkInvalid)
        elif res['Stat'] == ChessReturnStat.ChessBattled:
            # 已被其他君王击败，无法攻击
            raise GameException(TipsInfo.CrossChessActivity.ChessBattled)
        elif res['Stat'] == ChessReturnStat.ChessBattledNotMark:
            # 已被其他君王击败，无法标记
            raise GameException(TipsInfo.CrossChessActivity.ChessBattledNotMark)
        elif res['Stat'] == ChessReturnStat.ChessActivityNotStart:
            # 活动未开启
            raise GameException(TipsInfo.CrossChessActivity.ChessActivityNotStart)
        elif res['Stat'] == ChessReturnStat.ChessActivityClose:
            # 活动已关闭
            raise GameException(TipsInfo.CrossChessActivity.ChessActivityClose)

        elif res['Stat'] in Normal_Stat:
            raise GameException(res['Info'])
        else:
            del res['Stat']

        return res


class CrossMarryResponse(ResponseBase):
    """
    跨服联姻返回数据
    """

    @staticmethod
    def normal_response(res):
        """
        常规返回结果处理
        RoleNotExit = 1             # 角色不存在
        PrinceMarried = 2           # 皇子已成亲
        AskSeekRefused = 3          # 求亲已被拒绝
        AskSeekAccepted = 4         # 求亲已被接受
        AskSeekCancel = 5           # 求亲已被取消
        SeekMatched = 6             # 招亲已匹配
        SeekCancel = 7              # 招亲已取消
        SeekMarried = 8             # 招亲已被迎娶
        princeAttributeError = 9    # 皇子属性不匹配
        princeSexualError = 10      # 皇子性别不匹配
        DataError = 11              # 数据错误
        WaitForOpen = 12            # 区服未加入
        :param res:
        :return:
        """
        if res["Stat"] == CrossPrinceMarryReturnStat.RoleNotExit:
            # 角色不存在
            raise GameException(TipsInfo.RoleKeys.notFindCorrespondRole)
        elif res["Stat"] == CrossPrinceMarryReturnStat.PrinceMarried:
            # 皇子已结婚
            raise GameException(TipsInfo.PrinceKeys.princeAlreadyMarried)
        elif res["Stat"] == CrossPrinceMarryReturnStat.SeekCancel:
            # 招亲已取消
            raise GameException(TipsInfo.PrinceKeys.seekMateRecordError)
        elif res["Stat"] == CrossPrinceMarryReturnStat.SeekMarried:
            # 招亲方已联姻
            raise GameException(TipsInfo.PrinceKeys.seekMateAlreadyMarried)
        elif res["Stat"] == CrossPrinceMarryReturnStat.princeSexualError:
            # 皇子性别不符
            raise GameException(TipsInfo.PrinceKeys.princeSexualError)
        elif res["Stat"] == CrossPrinceMarryReturnStat.princeAttributeError:
            # 皇子属性不符
            raise GameException(TipsInfo.PrinceKeys.princeAttributeError)
        elif res["Stat"] == CrossPrinceMarryReturnStat.DataError:
            # 数据错误
            raise GameException(TipsInfo.RoleKeys.dataError)
        elif res["Stat"] == CrossPrinceMarryReturnStat.WaitForOpen:
            # 区服未加入
            raise GameException(TipsInfo.PrinceKeys.WaitForOpen)

        elif res["Stat"] in Normal_Stat:
            raise GameException(res["Info"])
        else:
            del res["Stat"]
            del res['ActionId']

        return {"status": True, "Res": res}


class CrossSoccerResponse(ResponseBase):
    """
    跨服足球返回数据
    """
    @staticmethod
    def normal_response(res):
        if res['Stat'] == SoccerReturnStat.ActivityOver:
            # 活动已结束
            raise GameException(TipsInfo.CrossActivity.ActivityOver)
        elif res['Stat'] == SoccerReturnStat.ParamError:
            # 参数错误
            raise GameException(TipsInfo.GlobalKeys.paramError)
        elif res['Stat'] == SoccerReturnStat.DataError:
            # 数据错误
            raise GameException(TipsInfo.RoleKeys.dataError)
        elif res['Stat'] == SoccerReturnStat.CfgError:
            # 配置数据出错
            raise GameException(TipsInfo.RoleKeys.getCfgError)
        elif res['Stat'] == SoccerReturnStat.BoxAlreadyOverdue:
            # 红包宝箱过期
            raise GameException(TipsInfo.ChatKeys.RedOverdue)
        elif res['Stat'] in Normal_Stat:
            raise GameException(res['Info'])
        else:
            del res['Stat']

        return {'Res': res}


class CrossRehearseResponse(ResponseBase):
    """
    跨服健锐返回数据
    """
    @staticmethod
    def normal_response(res):
        if res['Stat'] == RehearseReturnStat.ActivityOver:
            # 活动已结束
            raise GameException(TipsInfo.CrossActivity.ActivityOver)
        elif res['Stat'] == RehearseReturnStat.ParamError:
            # 参数错误
            raise GameException(TipsInfo.GlobalKeys.paramError)
        elif res['Stat'] == RehearseReturnStat.DataError:
            # 数据错误
            raise GameException(TipsInfo.RoleKeys.dataError)
        elif res['Stat'] == RehearseReturnStat.CfgError:
            # 配置数据出错
            raise GameException(TipsInfo.RoleKeys.getCfgError)
        elif res['Stat'] in [GlobalErrCode.ERROR, GlobalErrCode.FAILED, GlobalErrCode.ILLEGAL_ACTION,
                             GlobalErrCode.SERVER_MAINTAINING, GlobalErrCode.PLEASE_TRY_AGAIN]:
            raise GameException(res['Info'])
        else:
            del res['Stat']

        return {'Res': res}


class CrossLiveActivityResponse(ResponseBase):
    """
    直播活动返回数据
    """
    pass


class CrossQueenResponse(ResponseBase):
    """
    跨服健锐返回数据
    """
    @staticmethod
    def normal_response(res):
        if not res or 'Stat' not in res:
            return None
        elif res['Stat'] in Normal_Stat:
            raise GameException(res['Info'])
        else:
            del res['Stat']

        return res

    @classmethod
    def response_callback(cls, res, try_consistent=False):
        """
        对外调用的返回处理
        :param res: 返回结果
        :param try_consistent: 远程服务不可用时 是否尝试一致性处理
        :return:
        """
        try:
            if not res or 'Stat' not in res:
                # 无返回结果
                return None
        except Exception as e:
            return None
        finally:
            # TODO 暂时不删除此次请求的跨服的操作记录
            pass
            # if try_consistent:
            #     DistributedTransactionStatRepository.delete_by_trace_id(get_trace_id())
        return cls.do_response(res)
